package com.htt.bms.config;

import com.htt.bms.security.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;

/**
 * @author 侯婷婷
 * @version 1.0
 * @description spring security 配置类
 */
@Slf4j
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{

    @Autowired
    //当UserDetailsService实现类有多个时，指定自动封装的实现类
    //@Qualifier(value = "DBUserDetailsManager")
    @Qualifier(value = "userDetailServiceImpl")
    private UserDetailsService userDetailsService;

    /**
     * 基于内存的用户认证
     * @return
     */
    /*@Bean
    public UserDetailsService userDetailsService(){
        //创建UserDetailsService的实现类InMemoryUserDetailsManager implements UserDetailsManager, UserDetailsPasswordService
        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
        //向manager中添加对象
        manager.createUser(
                User.withDefaultPasswordEncoder().username("htt").password("123").roles("User").build()
        );
        manager.createUser(
                User.withDefaultPasswordEncoder().username("abc").password("123").roles("User").build()
        );
        return manager;
    }*/


    /**
     * 用于密码存储和校验
     * @return
     */
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    /**
     * AuthenticationProvider提供身份认证逻辑 调用UserDetailsService和PassworderEncoder接口
     * @return
     */
    @Bean
    public AuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
        provider.setUserDetailsService(userDetailsService);
        provider.setPasswordEncoder(passwordEncoder());
        return provider;
    }

    /**
     * 配置过滤器链
     * @param http
     * @return
     * @throws Exception
     */
    /*@Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{
        http.cors()
                .and()
                .csrf()
                .disable();

        http.authorizeRequests()
                .antMatchers("/hello")
                .permitAll()
                .anyRequest()
                .authenticated();

        http.formLogin(Customizer.withDefaults());

        http.addFilterBefore()

        // http.addFilter(new JWTAuthenticationFilter(new ProviderManager()));

        http.logout()
                .logoutUrl("/user/logout")
                .logoutSuccessHandler(new JWTLogoutSuccessHandler());
        return http.build();
    }*/

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors()
                .and()
                .csrf()
                .disable();

        http.authorizeRequests()
                .antMatchers("/hello")
                .permitAll()
                .anyRequest()
                .authenticated();

        http.formLogin().loginPage("/user/login")
                .permitAll()
                .usernameParameter("username")
                .passwordParameter("password");


        http.addFilter(new JWTAuthenticationFilter(authenticationManager()))
                .addFilter(new JWTAuthorizationFilter(authenticationManager()));


        http.exceptionHandling().authenticationEntryPoint(new JWTAuthenticationEntryPoint())
                .accessDeniedHandler(new JWTAccessDeniedHandler());

        http.logout()
                .logoutUrl("/user/logout")
                .logoutSuccessHandler(new JWTLogoutSuccessHandler());
    }
}
